# 用户认证模块

from django import forms
from web.models import Users
from django.contrib.auth.hashers import check_password, make_password
from django.http import JsonResponse
from web.apis import tools
from django.forms.models import model_to_dict
# 临时去除CSRF
from django.views.decorators.csrf import csrf_exempt
"""
check_password: 检查密码是否正确
make_password: 加密密码
"""

class UserregisterForm(forms.ModelForm):
    class Meta:
        model = Users
        fields = "__all__"

    def clean_password(self):
        password = self.cleaned_data.get('password')
        if not password:
            raise forms.ValidationError("密码不能为空")
            
        if not (6 <= len(password) <= 12):
            raise forms.ValidationError(f"密码长度必须在6到12个字符之间，当前长度: {len(password)}")
            
        if not all(char.isdigit() or char.isalpha() or char == '@' for char in password):
            raise forms.ValidationError("密码只能包含数字、英文和一个@符号")

        # 加密密码
        return make_password(password)

    def clean_username(self):
        username = self.cleaned_data.get('username')
        if not (2 <= len(username) <= 6):
            raise forms.ValidationError("用户名长度必须在2到6个字符之间")
        return username


# 注册用户
@csrf_exempt
def register(request):
    if request.method == 'POST':
        # 同时处理POST数据和文件上传
        form = UserregisterForm(request.POST, request.FILES)
        if form.is_valid():
            try:
                form.save()
                # 返回用户信息
                user = form.instance
                user_dict = model_to_dict(user)
                del user_dict['password']

                user_dict['create_time'] = user.create_time.strftime('%Y-%m-%d %H:%M:%S')
                user_dict['update_time'] = user.update_time.strftime('%Y-%m-%d %H:%M:%S')
                user_dict['avatar'] = user.avatar.url if user.avatar else None
                return JsonResponse(tools.ReturnData(code=200, msg='用户注册成功', data=user_dict))
            except Exception as e:
                return JsonResponse(tools.ReturnData(code=400, msg=f'保存用户数据失败: {str(e)}'))
        else:
            # 获取第一个错误信息
            error_msg = tools.get_first_error(form)
            return JsonResponse(tools.ReturnData(code=400, msg=f' {error_msg}'))
    else:
        return JsonResponse(tools.ReturnData(code=400, msg='请使用POST方法'))


class UserLoginForm(forms.Form):
    username = forms.CharField(required=True, error_messages={'required': '用户名不能为空'})
    password = forms.CharField(required=True, error_messages={'required': '密码不能为空'})

    def clean(self):
        cleaned_data = super().clean()
        username = cleaned_data.get('username')
        password = cleaned_data.get('password')
        
        if username and password:
            user = Users.objects.filter(username=username).first()
            if not user:
                raise forms.ValidationError("用户名不存在")
            if not check_password(password, user.password):
                raise forms.ValidationError("密码错误")
            # 将用户对象添加到cleaned_data中，以便在视图中使用
            cleaned_data['user'] = user
        return cleaned_data

# 登录
@csrf_exempt
def login(request):
    if request.method == 'POST':
        form = UserLoginForm(request.POST)
        if form.is_valid():
            try:
                user = form.cleaned_data['user']
                user_dict = model_to_dict(user)
                del user_dict['password']
                user_dict['create_time'] = user.create_time.strftime('%Y-%m-%d %H:%M:%S')
                user_dict['update_time'] = user.update_time.strftime('%Y-%m-%d %H:%M:%S')
                user_dict['avatar'] = user.avatar.url if user.avatar else None


                # 将用户信息存储到session中
                request.session['user'] = user_dict
                request.session.set_expiry(6000)
                return JsonResponse(tools.ReturnData(code=200, msg='登录成功', data=user_dict))
            except Exception as e:
                return JsonResponse(tools.ReturnData(code=400, msg=f'登录失败: {str(e)}'))
        else:
            error_msg = tools.get_first_error(form)
            return JsonResponse(tools.ReturnData(code=400, msg=f' {error_msg}'))
    else:
        return JsonResponse(tools.ReturnData(code=400, msg='请使用POST方法'))


class UserUpdateForm(forms.ModelForm):
    class Meta:
        model = Users
        fields = ['username', 'email', 'avatar', 'is_superuser']
        error_messages = {
            'username': {
                'unique': '用户名已经存在',
                'max_length': '用户名不能超过100个字符',
            },
            'email': {
                'unique': '邮箱已经存在',
                'invalid': '邮箱格式不正确',
            }
        }

    def clean_username(self):
        username = self.cleaned_data.get('username')
        if not (2 <= len(username) <= 6):
            raise forms.ValidationError("用户名长度必须在2到6个字符之间")
        return username


# 获取用户列表
@csrf_exempt
def get_user_list(request):
    if request.method == 'GET':
        try:
            users = Users.objects.all()
            user_list = []
            for user in users:
                user_dict = model_to_dict(user)
                del user_dict['password']
                user_dict['create_time'] = user.create_time.strftime('%Y-%m-%d %H:%M:%S')
                user_dict['update_time'] = user.update_time.strftime('%Y-%m-%d %H:%M:%S')
                user_dict['avatar'] = user.avatar.url if user.avatar else None
                user_list.append(user_dict)
            return JsonResponse(tools.ReturnData(code=200, msg='获取用户列表成功', data=user_list))
        except Exception as e:
            return JsonResponse(tools.ReturnData(code=400, msg=f'获取用户列表失败: {str(e)}'))
    else:
        return JsonResponse(tools.ReturnData(code=400, msg='请使用GET方法'))


# 获取单个用户信息
@csrf_exempt
def get_user(request, user_id):
    if request.method == 'GET':
        try:
            user = Users.objects.filter(id=user_id).first()
            if not user:
                return JsonResponse(tools.ReturnData(code=400, msg='用户不存在'))
            
            user_dict = model_to_dict(user)
            del user_dict['password']
            user_dict['create_time'] = user.create_time.strftime('%Y-%m-%d %H:%M:%S')
            user_dict['update_time'] = user.update_time.strftime('%Y-%m-%d %H:%M:%S')
            user_dict['avatar'] = user.avatar.url if user.avatar else None
            return JsonResponse(tools.ReturnData(code=200, msg='获取用户信息成功', data=user_dict))
        except Exception as e:
            return JsonResponse(tools.ReturnData(code=400, msg=f'获取用户信息失败: {str(e)}'))
    else:
        return JsonResponse(tools.ReturnData(code=400, msg='请使用GET方法'))


# 删除用户
@csrf_exempt
def delete_user(request, user_id):
    if request.method == 'DELETE':
        try:
            user = Users.objects.filter(id=user_id).first()
            if not user:
                return JsonResponse(tools.ReturnData(code=400, msg='用户不存在'))
            
            user.delete()
            return JsonResponse(tools.ReturnData(code=200, msg='删除用户成功'))
        except Exception as e:
            return JsonResponse(tools.ReturnData(code=400, msg=f'删除用户失败: {str(e)}'))
    else:
        return JsonResponse(tools.ReturnData(code=400, msg='请使用DELETE方法'))


# 更新用户信息
@csrf_exempt
def update_user(request, user_id):
    if request.method == 'POST':
        try:
            user = Users.objects.filter(id=user_id).first()
            if not user:
                return JsonResponse(tools.ReturnData(code=400, msg='用户不存在'))
            
            form = UserUpdateForm(request.POST, request.FILES, instance=user)
            if form.is_valid():
                form.save()
                user_dict = model_to_dict(form.instance)
                del user_dict['password']
                user_dict['create_time'] = form.instance.create_time.strftime('%Y-%m-%d %H:%M:%S')
                user_dict['update_time'] = form.instance.update_time.strftime('%Y-%m-%d %H:%M:%S')
                user_dict['avatar'] = form.instance.avatar.url if form.instance.avatar else None
                return JsonResponse(tools.ReturnData(code=200, msg='更新用户信息成功', data=user_dict))
            else:
                error_msg = tools.get_first_error(form)
                return JsonResponse(tools.ReturnData(code=400, msg=f' {error_msg}'))
        except Exception as e:
            return JsonResponse(tools.ReturnData(code=400, msg=f'更新用户信息失败: {str(e)}'))
    else:
        return JsonResponse(tools.ReturnData(code=400, msg='请使用POST方法'))
        
